<?php

namespace App\Services;

/**
 * 微信管理
 *
 * @Author hechengwei
 * @email chichiooo@sina.com
 * @DateTime 2022-03-21
 */
class WechatMassageService
{

    private $appId;
    private $appSecret;

    public function __construct()
    {
        $this->appId = env('WECHAT_OPEN_PLATFORM_APPID');
        // $this->appId = 'wx8aca29e958e45c20';
        $this->appSecret = env('WECHAT_OPEN_PLATFORM_SECRET');
        // $this->appSecret = '76f124f9cb62e5e116273ba6a207efa2';

    }


    //https请求，支持post.get
    protected function http_request($url, $data = NULL)
    {
        $curl = curl_init();
        // $header = "Accept-Charset: utf-8";
        $header = array('Accept-Charset: utf-8');
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
        curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($curl, CURLOPT_AUTOREFERER, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        $temp = curl_exec($curl);
        curl_close($curl);
        return $temp;
    }
    private function httpGet($url)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($curl, CURLOPT_AUTOREFERER, 1);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        $temp = curl_exec($curl);
        curl_close($curl);
        return $temp;
    }
    //js的相关配置
    public function getSignPackage()
    {
        $jsapiTicket = $this->getJsApiTicket();
        // 注意 URL 一定要动态获取，不能 hardcode.
        $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
        $url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";

        $timestamp = time();
        $nonceStr = $this->createNonceStr();

        // 这里参数的顺序要按照 key 值 ASCII 码升序排序
        $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";

        $signature = sha1($string);

        $signPackage = array(
            "appId"     => $this->appId,
            "nonceStr"  => $nonceStr,
            "timestamp" => $timestamp,
            "url"       => $url,
            "signature" => $signature,
            "rawString" => $string
        );
        return $signPackage;
    }
    //随机吗
    private function createNonceStr($length = 16)
    {
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }
    //获取Ticket
    private function getJsApiTicket()
    {
        // jsapi_ticket 应该全局存储与更新，以下代码以写入到文件中做示例
        $data = json_decode(file_get_contents(storage_path('/wechat/jsapi_ticket.json')));
        if ($data->expire_time < time()) {
            $accessToken = $this->getAccessToken();
            // 如果是企业号用以下 URL 获取 ticket
            $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=$accessToken";
            $res = json_decode($this->httpGet($url));
            $ticket = $res->ticket;
            if ($ticket) {
                $data->expire_time = time() + 7000;
                $data->jsapi_ticket = $ticket;
                $fp = fopen(storage_path('/wechat/jsapi_ticket.json'), "w");
                fwrite($fp, json_encode($data));
                fclose($fp);
            }
        } else {
            $ticket = $data->jsapi_ticket;
        }
        return $ticket;
        exit;
    }
    //获取微信access_token
    public function getAccessToken()
    {
        // access_token 应该全局存储与更新，以下代码以写入到文件中做示例
        $data = json_decode(file_get_contents(storage_path('/wechat/access_token.json')));
        if ($data->expire_time < time()) {
            // 如果是企业号用以下URL获取access_token
            $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $this->appId . "&secret=" . $this->appSecret;
            $res = json_decode($this->httpGet($url));
            $access_token = $res->access_token;

            if ($access_token) {
                $data->expire_time = time() + 7000;
                $data->access_token = $access_token;
                $fp = fopen(storage_path('/wechat/access_token.json'), "w");
                fwrite($fp, json_encode($data));
                fclose($fp);
            }
        } else {
            $access_token = $data->access_token;
        }
        return $access_token;
    }


    public function access_token($code)
    {
        if (!$code) {
            $userinfo = array('stats' => '-1', 'msg' => '无法获取code');
        }
        $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" . $this->appId . "&secret=" . $this->appSecret
            . "&code=" . $code . "&grant_type=authorization_code";
        $res = json_decode($this->http_request($url));
        return $res;
    }

    public function jmgetCode($redirect_uri)
    {
        return redirect("https://open.weixin.qq.com/connect/oauth2/authorize?appid=" . $this->appId . "&redirect_uri=" . $redirect_uri . "&response_type=code&scope=snsapi_base&state=JMSTATECODE#wechat_redirect");
    }

    public function returnUrl($redirect_uri)
    {
        return redirect("https://open.weixin.qq.com/connect/oauth2/authorize?appid=" . $this->appId . "&redirect_uri=" . $redirect_uri . "&response_type=code&scope=snsapi_userinfo&state=GETCODE#wechat_redirect");
    }
    public function getCode($redirect_uri)
    {
        return redirect("https://open.weixin.qq.com/connect/oauth2/authorize?appid=" . $this->appId . "&redirect_uri=" . $redirect_uri . "&response_type=code&scope=snsapi_userinfo&state=GETCODE#wechat_redirect");
    }

    public function returnUrl1($redirect_uri)
    {
        return ("https://open.weixin.qq.com/connect/qrconnect?appid=" . $this->appId . "&redirect_uri=" . $redirect_uri . "&response_type=code&scope=snsapi_login&state=STATE#wechat_redirect");
    }



    //获取openid
    public function openid($code = "")
    {
        if (empty($code)) {
            $code = $_GET['code'];
        }
        //模拟浏览器请求
        $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" . $this->appId . "&secret=" . $this->appSecret . "&code={$code}&grant_type=authorization_code";
        $Token_data = (array) json_decode($this->http_request($url));
        if (!empty($Token_data['openid'])) {
            return $Token_data;
        } else {
            return $Token_data;
        }
        exit;
    }

    public function wxuserinfo($access_token, $openid)
    {
        $userurl = "https://api.weixin.qq.com/sns/userinfo?access_token=" . $access_token . "&openid=" . $openid . "&lang=zh_CN";
        $userinfo = json_decode($this->httpGet($userurl));
        return $userinfo;
    }

    //获取个人信息
    public function getPersonInfo($openid)
    {
        $access_token = $this->getAccessToken();
        $url = "https://api.weixin.qq.com/sns/userinfo?access_token=" . $access_token . "&openid=" . $openid . "&lang=zh_CN";
        $array = (array) json_decode($this->httpGet($url));
        return $array;
    }

    //发送模板消息
    public function send_template_message($data)
    {
        $access_token = $this->getAccessToken();
        $url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" . $access_token;
        $res = $this->http_request($url, $data);
        return json_decode($res, true);
    }


    //自定义菜单
    public function menu_create($data)
    {
        $access_token = $this->getAccessToken();
        $url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" . $access_token;
        $res = $this->http_request($url, $data);
        return json_decode($res, true);
    }

    /* 创建二维码
	 *@param - $qrcodeID传递的参数
	 *$qrcodeType二维码类型 默认为临时二维码
	 *@return - 返回二维码图片地址
	 */
    public function QrcodeCreate($qrcodeID, $qrcodeType = 0)
    {
        if ($qrcodeType == 0) {
            $qrcodeType = 'QR_SCENE';
        } else {
            $qrcodeType = 'QR_LIMIT_SCENE';
        }
        $tempJson = '{"expire_seconds": 604800, "action_name": "' . $qrcodeType . '", "action_info": {"scene": {"scene_id": ' . $qrcodeID . '}}}';

        $access_token = $this->getAccessToken();

        $url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" . $access_token;
        $tempArr = json_decode($this->http_request($url, $tempJson), true);
        if (@array_key_exists('ticket', $tempArr)) {
            return 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=' . $tempArr['ticket'];
        }
    }
    public function moneyinfo($dataArr)
    {
        if (!empty($dataArr)) {
            $dataArr['mch_appid'] = $this->appId;
            $signinfo = $this->getSign($dataArr);
            if ($signinfo['status'] != "-1" && $signinfo['status'] != "-2") {
                $XMLINFO = "<xml>
		            <mch_appid>" . $dataArr['mch_appid'] . "</mch_appid>
		            <mchid>" . $dataArr['mchid'] . "</mchid>
		            <nonce_str>" . $dataArr['nonce_str'] . "</nonce_str>
		            <partner_trade_no>" . $dataArr['partner_trade_no'] . "</partner_trade_no>
		            <openid>" . $dataArr['openid'] . "</openid>
		            <check_name>" . $dataArr['check_name'] . "</check_name>
		            <re_user_name>" . $dataArr['re_user_name'] . "</re_user_name>
		            <amount>" . $dataArr['amount'] . "</amount>
		            <desc>" . $dataArr['desc'] . "</desc>
		            <spbill_create_ip>" . $dataArr['spbill_create_ip'] . "</spbill_create_ip>
		            <sign>" . $signinfo . "</sign>
		            </xml>";
                return $XMLINFO;
            } else {
                return $signinfo;
            }
        } else {
            return array("status" => '-1', "msg" => 'dataArr错误');
        }
    }

    public function remitinfo($data)
    {
        if (!empty($data)) {
            $data['appid'] = $this->appId;
            $signinfo = $this->getSign($data);
            if ($signinfo['status'] != "-1" && $signinfo['status'] != "-2") {
                $XMLINFO = "<xml>
     			<sign><![CDATA[" . $signinfo . "]]></sign>
     				<partner_trade_no><![CDATA[" . $data['partner_trade_no'] . "]]></partner_trade_no>
     				<mch_id><![CDATA[" . $data['mch_id'] . "]]></mch_id>
     				<appid><![CDATA[" . $data['appid'] . "]]></appid>
     				<nonce_str><![CDATA[" . $data['nonce_str'] . "]]></nonce_str>
				</xml>";
                return $XMLINFO;
            } else {
                return $signinfo;
            }
        } else {
            return array("status" => '-1', "msg" => 'dataArr错误');
        }
    }
    /**
     * 	作用：格式化参数，签名过程需要使用
     */
    private function getSign($Obj)
    {
        if (empty($Obj)) {
            return array("status" => '-2', "msg" => '生成签名数据为空');
        }
        foreach ($Obj as $k => $v) {
            $Parameters[$k] = $v;
        }

        //按字典序排序参数
        ksort($Parameters);
        $String = $this->generateGetSign($Parameters, false);
        if ($String == "") {
            return array("status" => "-3", "msg" => "生成签名失败");
        }
        //在string后加入key,key值不可随意修改
        $String = $String . "&key=shixiPlus2502zaqxswcdevfrbgtnhym";
        //md5加密
        $String = md5($String);
        //所有字符转为大写
        $result = strtoupper($String);
        return $result;
    }
    /**
     * 	作用：生成签名
     */
    private function generateGetSign($paraMap, $urlencode)
    {
        $buff = "";
        ksort($paraMap);
        foreach ($paraMap as $k => $v) {
            if ($urlencode) {
                $v = urlencode($v);
            }
            $buff .= $k . "=" . $v . "&";
        }
        $reqPar;
        if (strlen($buff) > 0) {
            $reqPar = substr($buff, 0, strlen($buff) - 1);
        }
        return $reqPar;
    }


    //下载多媒体文件
    public function saveMedia($MEDIA_ID)
    {
        $access_token = $this->getAccessToken();
        $url = "https://api.weixin.qq.com/cgi-bin/media/get?access_token=" . $access_token . "&media_id=" . $MEDIA_ID . "";
        //$url = "https://api.weixin.qq.com/cgi-bin/media/get/jssdk?access_token=".$access_token."&media_id=".$MEDIA_ID."";
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_NOBODY, 0);    //对body进行输出。
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $package = curl_exec($ch);
        $httpinfo = curl_getinfo($ch);

        curl_close($ch);
        $media = array_merge(array('mediaBody' => $package), $httpinfo);

        //求出文件格式
        preg_match('/\w\/(\w+)/i', $media["content_type"], $extmatches);
        $fileExt = $extmatches[1];
        $filename = time() . rand(100, 999) . ".{$fileExt}";
        $dirname = "./Upload/wxmedia/";
        if (!file_exists($dirname)) {
            mkdir($dirname, 0777, true);
        }
        file_put_contents($dirname . $filename, $media['mediaBody']);

        return $filename;
    }

    /**
     * 微信推送消息
     */
    public function sendMessage($toUser, $content)
    {
        $token = $this->getAccessToken();
        $data = '{
        "touser":"' . $toUser . '",
        "msgtype":"text",
        "text":
            {
                 "content":"' . $content . '"
            }
             }';

        $url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" . $token;
        $result = $this->http_request($url, $data);
        return json_decode($result, true);
    }

    //获取微信access_token
    public function getAccessToken2()
    {

        // access_token 应该全局存储与更新，以下代码以写入到文件中做示例
        $data = json_decode(file_get_contents(storage_path('/wechat/access_token.json')));

        if ($data->expire_time < time()) {
            // 如果是企业号用以下URL获取access_token
            $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . env('WECHAT_OFFICIAL_PLATFORM_APPID') . "&secret=" . env('WECHAT_OFFICIAL_PLATFORM_SECRET');

            $res = json_decode($this->httpGet($url));

            $access_token = $res->access_token;

            if ($access_token) {
                $data->expire_time = time() + 7000;
                $data->access_token = $access_token;
                $fp = fopen(storage_path('/wechat/access_token.json'), "w");
                fwrite($fp, json_encode($data));
                fclose($fp);
            }
        } else {

            $access_token = $data->access_token;
        }
        return $access_token;
    }
    public function getUserFocus($openId)
    {
        $access_token = $this->getAccessToken2();
        $url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" . $access_token . "&openid=" . $openId . "&lang=zh_CN";
        // dd($url);
        $userinfo = json_decode($this->httpGet($url), true);
        dd($userinfo);
        return $userinfo;
    }
}
